/********************************************************/
/*                                                      */
/*               CLASS ColorPicker                      */
/*------------------------------------------------------*/
/* Constructeur                                         */
/* [object ColorPicker] ColorPicker(id,[initialColor])  */
/*   id : id du contenaire dans le DOM                  */
/*   initialColor : couleur au chargement, en Hex       */
/*                  Exemple '#FF0000'                   */
/*					Cet argument n'est pas obligatoire  */
/*------------------------------------------------------*/
/*   Dépendances:                                       */
/*      -colorPicker.colorspaceConvertion.js            */
/*      -colorPicker.simpleColorConvertion.js           */
/*------------------------------------------------------*/
/*   Par MaX3315                                        */
/*   http://codessources.votre-web.com                  */
/********************************************************/
function ColorPicker(_id,_realTimeCallBack)
{
	this.version='1.0';							//version du color picker
	this.id=_id;								//id du color picker
	this.obj=document.getElementById(this.id);	//obj container du color picker
	this.win=window.self;						//fenetre du color picker (permet un usage au travers de popup)
	var realTimeCallBackArg=null;				//fonction de call abck appeler par this.refreshCurrentColor  (voir plus bas)
	if(typeof(_realTimeCallBack)!='undefined' && _realTimeCallBack!=null) { realTimeCallBackArg=_realTimeCallBack; }
	this.selecteurMode='perceptual';			//mode du selecteur actuel
	this.actualZ='r';							//axe d'edition peut-etre r,g,b ou h,s,v     cf les input radio
	this.step=16;								//precision du selecteur perceptuel
	this.precisionBeforeTabPannelSwitch=this.step;	//precision du selecteur perceptuel avant l'affichage d'un autre seleceteur
	this.squareWidth=256/this.step;				//deduction de la largeur d'une cellule du selecteur
	this.x=0;									//valeur du curseur x
	this.y=0;									//					y
	this.z=0;									//					z
	this.beginColor=readCookie('colorPicker_'+this.id+'_lastColor');		// couleur à l'ouverture
//	this.historyColors=Array(18);			//les couleurs dans le nuancier historique
	this.currentHistoryIdSelected=0;
	this.realTimeCallBack=realTimeCallBackArg;
	this.realTimeCookieWriteThread=null;
	//les pluggins
	this.pluggins=Array();
	this.warningZoneInUse=0; 

	
	//coordonnes de la zone de dragXY
	this.xDecal=0;
	this.yDecal=0;
	//objet layer de ce color picker
	this.xySpaceLayer=null;
	this.xyDragLayer=null;
	this.zSpaceLayer=null;
	this.zDragLayer=null;
	//pointer dragable
	this.xyPointer=null;
	this.zPointer=null;
	//zone de preview couleur
	this.currentSpace=null;
	this.currentSpaceOld=null;

	//méthodes de l'objet color picker  (commence toute par CP_
	this.init=CP_init;
	this.registerMe=CP_registerMe;
	this.changeSelector=CP_changeSelector;  //anciennement show(value)
	this.acquireXY=CP_acquireXY;
	this.acquireZ=CP_acquireZ;
	this.changePrecision=CP_changePrecision;
	this.change=CP_change;
	this.set=CP_set;
	this.get=CP_get;
	this.drawVariableSpace=CP_drawVariableSpace;
	this.initVariableSpace=CP_initVariableSpace;
	this.initGrid=CP_initGrid;
	this.drawGrid=CP_drawGrid;
	this.injectHTML=CP_injectHTML;
	this.initHistoryList=CP_initHistoryList;
	this.refreshCurrentColor=CP_refreshCurrentColor;
	//méthode spécifiques aux pluggins
	/*
	   Les pluggins devront posséder un certain nomrbre de fonction permettant:
		- de dessiner leur sélecteur dans la zone (de 286x256 px)
		- devront pouvoir traiter la saisie d'une nouvelle couleur
	   Ces pluggins pourront
		- utiliser la petite zone en bas (de x px)
		- utiliser la zone libre (de 100x82 px)
	*/
	this.registerPluggin=CP_registerPluggin;
	this.hidePlugginsSelector=CP_hidePlugginsSelector;
}

/*************************************************/
/*                                               */
/*    Méthodes privées de la class ColorPicker   */
/*                                               */
/* Par commodité j'ai indéxer toutes les méthodes*/
/*  par CP_  comme Color Picker                  */
/*************************************************/

//Méthode d'initialisation d'un color picker
//  Cette méthode va insérer le code html
//  Initliser toute les valeurs par défault, et les valeurs déduites de celle-ci
//  Positionner les calques absolus (pointer, zone de drag, etc...)
//  Initialiser les deux zones de dégradée
function CP_init()
{
	if(this.beginColor==null) { this.beginColor='#FF0000'; }  //on vérifie qu'il y a bien une couleur de spécifier
	//on trace le colorpicker!
	this.injectHTML();
	
	//calcul du positionnement absolue
	var tmp=getAbsolutePositionOf(document.getElementById(this.id+'_perceptualSelectorTable'));
	this.xDecal=tmp[0];
	this.yDecal=tmp[1];

	
	
	//on injecte le complement HTML n'écessaire à chaque pluggin
	for(var i=0 ; i<this.pluggins.length ; i++)
	{
		if(this.pluggins[i].injectHTML) { this.pluggins[i].injectHTML(); }
	}
	
	//on initialise tout les objets de ce color picker
	//td de la zone de selection de la qualite
	this.bottomQualityTd=document.getElementById(this.id+'_qualityTd');
	//les espace XY et Z
	this.xySpaceLayer=document.getElementById(this.id+'_variationEspace');
	this.xyDragLayer=document.getElementById(this.id+'_dragXY');
	this.zSpaceLayer=document.getElementById(this.id+'_variableEspace');
	this.zDragLayer=document.getElementById(this.id+'_dragZ');
	//les pointeurs
	this.xyPointer=document.getElementById(this.id+'_pointerXY');
	this.zPointer=document.getElementById(this.id+'_pointerZ');
	
	//on repositonne les calques du selecteur perceptuel et les curseurs
	this.xySpaceLayer.style.left=this.xDecal+'px';
	this.xySpaceLayer.style.top=this.yDecal+'px';
	this.xyDragLayer.style.left=this.xDecal+'px';
	this.xyDragLayer.style.top=this.yDecal+'px';
	this.zSpaceLayer.style.left=(this.xDecal+266)+'px';
	this.zSpaceLayer.style.top=this.yDecal+'px';
	this.zDragLayer.style.left=(this.xDecal+266)+'px';
	this.zDragLayer.style.top=this.yDecal+'px';

	//les layers perceptual
	this.xySpaceLayer.style.left=this.xDecal+'px';
	this.xySpaceLayer.style.top=this.yDecal+'px';
	this.xyDragLayer.style.left=this.xDecal+'px';
	this.xyDragLayer.style.top=this.yDecal+'px';
	this.zSpaceLayer.style.left=(this.xDecal+266)+'px';
	this.zSpaceLayer.style.top=this.yDecal+'px';
	this.zDragLayer.style.left=(this.xDecal+266)+'px';
	this.zDragLayer.style.top=this.yDecal+'px';
	//zone de couleur
	this.currentSpace=document.getElementById(this.id+'_currentSpace');
	this.currentSpaceOld=document.getElementById(this.id+'_currentSpaceOld');
	this.currentSpaceOld.style.backgroundColor=this.beginColor;
	
	//pointer draguables
	this.xyPointer.style.left=(this.xDecal+153)+'px';
	this.xyPointer.style.top=(this.yDecal+153)+'px';
	this.zPointer.style.left=(this.xDecal+258)+'px';
	this.zPointer.style.top=(this.yDecal+153)+'px';
	
	//on rend visible els zone de drag et space
	this.xySpaceLayer.style.display='block';
	this.xyDragLayer.style.display='block';
	this.zSpaceLayer.style.display='block';
	this.zDragLayer.style.display='block';
	 
	//en enregistre ce colorpicker sur la page
	this.registerMe();
	this.initHistoryList();
	this.initVariableSpace(); //on init la zone Z
	this.initGrid();
	this.xySpaceLayer.style.display='block';
	this.xyDragLayer.style.display='block';
	this.set('hex',this.beginColor);
	this.change(document.getElementById(this.id+'_hex'));
	
	//on initialise tous les pluggins
	for(var i=0 ; i<this.pluggins.length ; i++)
	{
		if(this.pluggins[i].init) { this.pluggins[i].init(); }
	}
	
	
	//on recharge l'etat de ce color picker dans les cookies (quel selecteur a été utilise pour la dernière fois)
	var lastSelecteur=readCookie(this.id+'_last_mode_used');
	if(lastSelecteur==null) { lastSelecteur='perceptual'; }
	else
	{ //on verifie si le selecteur demandé existe bien, cela peut arrivé que non, si la config a changer
	  var itsok=false;
	  for(var i=0 ; i<this.pluggins.length ; i++)
	  {
		  if(this.pluggins[i].codeName==lastSelecteur && this.pluggins[i].needSelectorEntry) { itsok=true; }
	  }
	  if(!itsok) { lastSelecteur='perceptual'; }
	}
	this.changeSelector(lastSelecteur);
	return;
}


//rafraichi le degrade de la zone Z
// contrairement a la fonction ColorPicker.initVariableSpace()
//  celle si ne fait que modifier .style.backgroundColro des div de la zone Z, ce qui est bien plus rapide que les creer
function CP_drawVariableSpace()
{
	for(i=255 ; i>=0 ; i--)
	{
	  var ar;
	  switch(this.actualZ)
	  {
		case 'h':
			ar=HSV2RGB(Array(resampleColor(i,255,360,true),100,100));	//get('s'),get('v')
																		//on fixe les deux autres axes a 100 et 100 dans ce cas
																		//afin d'avoir el meme comportement que photoshop.
			break;
		case 's':
			ar=HSV2RGB(Array(this.get('h'),resampleColor(i,255,100,true),this.get('v')));
			break;
		case 'v':
			ar=HSV2RGB(Array(this.get('h'),this.get('s'),resampleColor(i,255,100,true)));
			break;
		case 'r':
			ar='rgb('+Array(i,this.get('g'),this.get('b'))+')';
			break;
		case 'g':
			ar='rgb('+Array(this.get('r'),i,this.get('b'))+')';
			break;
		case 'b':
			ar='rgb('+Array(this.get('r'),this.get('g'),i)+')';
			break;
	  }
	  var tmp=document.getElementById(this.id+'_variableZ_'+i);
	  if(tmp) { tmp.style.backgroundColor=ar; }
	}
}

//init le degrade de la zone Z
// creation des 256 div de la zone Z
//  Veuillez a utiliser la fnction ColorPicker.drawVariableSpace() pour rafraichir cette zone
//  en effet draw  est bien plus rapide que init  (init servant juste a creer une premiere fois la zone)
function CP_initVariableSpace()
{
	var str='';
	for(i=255 ; i>=0 ; i--)
	{
	  var ar;
	  switch(this.actualZ)
	  {
		case 'h':
			ar=HSV2RGB(Array(resampleColor(i,255,360,true),100,100));	//get('s'),get('v')
																		//on fixe les deux autres axes a 100 et 100 dans ce cas
																		//afin d'avoir el meme comportement que photoshop.
			break;
		case 's':
			ar=HSV2RGB(Array(this.get('h'),resampleColor(i,255,100,true),this.get('v')));
			break;
		case 'v':
			ar=HSV2RGB(Array(this.get('h'),this.get('s'),resampleColor(i,255,100,true)));
			break;
		case 'r':
			ar='rgb('+Array(i,this.get('g'),this.get('b'))+')';
			break;
		case 'g':
			ar='rgb('+Array(this.get('r'),i,this.get('b'))+')';
			break;
		case 'b':
			ar='rgb('+Array(this.get('r'),this.get('g'),i)+')';
			break;
	  }
	  str+='<div id="'+this.id+'_variableZ_'+i+'" style="height:1px; padding:0px; margin:0px; font-size:1px; background-color:'+ar+';"><img src="images/empty.gif"></div>';
	}
	this.zSpaceLayer.innerHTML=str;
}

//creer le tableau de taille 256x256 sans ce souciez des couleur, cf CP_drawGrid
// tout comme pour la zone Z veuillez utiliser draw pour els rafrachissement et init pour les initialisation
// dans ce cas init va etre appler pas que lors de la creation du color picker mais a chaque fois que
// l'utilisatuer chagera la resolution de la grille
function CP_initGrid()
{
	var str='<table style="width:256px; height:256px;" cellspacing="0" cellpadding="0">';
	var i,j;
	for(i=255 ; i>=0 ; i-=this.squareWidth)
	{
	  str+='<tr>';
	  if((i-this.squareWidth)<0) { i=0; }
	  for(j=0 ; j<256 ; j+=this.squareWidth)
	  {
		if((j+this.squareWidth)>255) { j=255; }
		str+='<td id="'+this.id+'_'+i+'_'+j+'" style="width:'+this.squareWidth+'px; height:'+this.squareWidth+'px;" class="tdEspace"><img src="images/empty.gif"></td>';
	  }
	  str+='</tr>';
	}
	str+='</table>';
	this.xySpaceLayer.innerHTML=str;
	this.drawGrid();
	return;
}

//fonction de rafrachissement 'rapide' de la grille perceptuel
//Assigne les couleur de fond a toutes les cellules que compose cette grille (le nombre dépend de la qualité d'affichage)
function CP_drawGrid()
{
	var i,j;
	var fixe=this.get(this.actualZ);
	
	for(i=255 ; i>=0 ; i-=this.squareWidth)
	{
	  if((i-this.squareWidth)<0) { i=0; }
	  for(j=0 ; j<256 ; j+=this.squareWidth)
	  {
		if((j+this.squareWidth)>255) { j=255; }
		var cl;
		switch(this.actualZ)
		{
		  case 'r':
			cl='rgb('+fixe+','+i+','+j+')';
			break;
		  case 'g':
			cl='rgb('+i+','+fixe+','+j+')';
			break;
		  case 'b':
			cl='rgb('+j+','+i+','+fixe+')';
			break;
		  case 'h':
			cl=HSV2RGB(Array(fixe,resampleColor(j,255,100,true),resampleColor(i,255,100,true)));
			break;
		  case 's':
			cl=HSV2RGB(Array(resampleColor(j,255,360,true),fixe,resampleColor(i,255,100,true)));
			break;
		  case 'v':
			cl=HSV2RGB(Array(resampleColor(j,255,360,true),resampleColor(i,255,100,true),fixe));
			break;
		}
		var tmp=document.getElementById(this.id+'_'+i+'_'+j);
		if(tmp) { tmp.style.backgroundColor=cl; } else { document.title=this.id+'_'+i+'_'+j+'  doesnt exist'; }
	  }
	}
	return;
}

//fonction cachant tous les sélecteur de tout les pluggins
function CP_hidePlugginsSelector()
{
	for(var i=0 ; i<this.pluggins.length ; i++)
	{
		if(this.pluggins[i].hideSelector) { this.pluggins[i].hideSelector(); }
	}
	return;
}

//fonction enregistrant un pluggin pour ce selecteur
function CP_registerPluggin(plugginObj)
{
	//on vérifie la compatibilité de version
	if(plugginObj.versionColorPickerNeeded<=this.version)
	{
		if(plugginObj.uniqueRegistration)
		{
			for(var i=0 ; i<this.pluggins.length ; i++)
			{
				if(this.pluggins[i].codeName==plugginObj.codeName)  //le même pluggin a déjà été téléchargé!
				{ alert(CP_LOCAL_pluggin_registration_error+' ('+plugginObj.name+').\n'+CP_LOCAL_pluggin_duplicate_registration); return; }
			}
		}
		if(plugginObj.needWarning)
		{
			if(this.warningZoneInUse>=4) { return; } /* il n'y a plus de zone warning dispo*/
			else { plugginObj.assignedWarningId=this.warningZoneInUse; this.warningZoneInUse++; }
		}
		this.pluggins.push(plugginObj);
		plugginObj.colorPicker=this;
		
	}
	else { alert(CP_LOCAL_pluggin_registration_error+' ('+plugginObj.name+').\n'+CP_LOCAL_pluggin_registration_to_old_color_picker); }
}

//enregistre ce colorpicker dans une liste Globale du script
// cette liste globale permet a la fonction global CP_findColorPickerById
// de pouvoir retourner une référence vers l'objet ColorPicker correspondant à un id
function CP_registerMe()
{
	CP_colorPickerList.push(this);
	return;
}


//Acquisition des nouvelles coordonnées X,Y
function CP_acquireXY()
{
	if(CP_mouseMode=='xy')
	{
		var valx=this.x;
		var valy=this.y;
		var changeWhatColorAxe=null;
		switch(this.actualZ)
		{
			case 'r':
				this.set('g',255-this.y);
				this.set('b',this.x);
				changeWhatColorAxe='b';
				break;
			case 'g':
				this.set('r',255-this.y);
				this.set('b',this.x);
				changeWhatColorAxe='r';
				break;
			case 'b':
				this.set('r',this.x);
				this.set('g',255-this.y);
				changeWhatColorAxe='g';
				break;
			case 'h':
				this.set('s',resampleColor(this.x,255,100,true));
				this.set('v',resampleColor(255-this.y,255,100,true));
				changeWhatColorAxe='s';
				break;
			case 's':
				this.set('h',resampleColor(this.x,255,360,true));
				this.set('v',resampleColor(255-this.y,255,100,true));
				changeWhatColorAxe='v';
				break;
			case 'v':
				this.set('h',resampleColor(this.x,255,360,true));
				this.set('s',resampleColor(255-this.y,255,100,true));
				changeWhatColorAxe='h';
				break;
		}
		if(changeWhatColorAxe!=null)
		{
			this.change(document.getElementById(this.id+'_'+changeWhatColorAxe));
		}
	}
}

//Acquisition de la nouvelle coordonnée Z
function CP_acquireZ()
{
	if(CP_mouseMode=='z')
	{
	  var val=this.z;
	  switch(this.actualZ)
	  {
		 case 'r':
		 case 'g':
		 case 'b':
			val=255-this.z;
			break;
		 case 'h':
		 case 's':
		 case 'v':
			val=resampleColor(255-this.z,255,100,true);
			break;
	  }
	  this.set(this.actualZ,val);
	  this.change(document.getElementById(this.id+'_'+this.actualZ));
	}
}

//Modification de la précision de la grille de la palette perceptual
function CP_changePrecision(newStep,hideMessage)
{
	if(document.getElementById(this.id+'_precision') && newStep>=32 && hideMessage!=true)
	{
	  if(!confirm(CP_LOCAL_hight_quality_warning)) { document.getElementById(this.id+'_precision').value=step; return; }
	}
	this.step=newStep;
	this.squareWidth=256/this.step;
	this.initGrid();
	this.drawVariableSpace();
	if(document.getElementById(this.id+'_precision'))
	{
	  document.getElementById(this.id+'_precision').value=this.step;
	}
}

//fonction raccoucis pour lire une valeur dans l'un des champs
// argument comp == composante ('hex','r','g','b','h','s','v','c','m','y','k')
function CP_get(comp) { var resu=this.win.document.getElementById(this.id+'_'+comp).value; if(resu=='undefined') { return 0; } return resu; }
//fonction raccoucis pour assigne ou lire une valeur dans l'un des champs
function CP_set(comp,value) { this.win.document.getElementById(this.id+'_'+comp).value=value; return true; }


//charge les couleur de l'historique depuis les cookies associer a ce color picker
// se chargement utilise l'id du colorpicker, ainsi chaque color picker ayant un id different
// aura un historique different de sauvegarde dans les cookies
function CP_initHistoryList()
{
	for(var i=0 ; i<18 ; i++)
	{
	   var tmp=readCookie(this.id+'_historyColor_'+i);
	   if(tmp!=null)
	   {
		 document.getElementById(this.id+'_historyTd_'+i).style.backgroundColor=tmp;
	   }
	}
}

//rafraichissement de la zone de preview de la couleur actuelle
// et transmission de cette information aux pluggins configure pour traiter cela
// sauvegarde différée dans un cookie (ce qui permet de réouvrir le même colorpicker avec etet dernier couleur choisie)
function CP_refreshCurrentColor()
{
	this.currentSpace.style.backgroundColor=this.get('hex');
	
	//appel des methode refreshCurrentColor des pluggins
	for(var i=0 ; i<this.pluggins.length ; i++)
	{
		if(this.pluggins[i].interceptRefreshColor==true)  //est ce que le pluggin est prevu pour intercepter les modif de couleur?
		{
			if(this.pluggins[i].refreshCurrentColor) { this.pluggins[i].refreshCurrentColor(); }
		}
	}
	
	//appel de la fonction de callback
	if(this.realTimeCallBack!=null) { this.realTimeCallBack(this); }
	
	//on sauvegarde la couleur courante dans un cookie pour pouvori la restituer à la prochaine ouverture
	if(this.realTimeCookieWriteThread!=null) { clearTimeout(this.realTimeCookieWriteThread); }
	this.realTimeCookieWriteThread=setTimeout("CP_saveCurrentColorToCookieForColorPicker('"+this.id+"')",CP_threadCookieColorSaveTimeoutMiliseconde);
}

//fonction sauvegardant la couleur actuellement sélectionnée au format 'hex'
// cette fonction est appeler en differe par ColorPicker.refreshCurrentColor()  cf CP_refreshCurrentColor
function CP_saveCurrentColorToCookieForColorPicker(idColorPicker)
{
	var colorPicker=CP_findColorPickerById(idColorPicker);
	if(colorPicker)
	{
		createCookie('colorPicker_'+colorPicker.id+'_lastColor',colorPicker.get('hex'),null,HISTORY_COOKIES_DOMAIN_PATH);
	}
	return;
}

//detection d'un changement au clavier d'une des composantes
function CP_change(obj)
{
	CP_controlValueInInput(obj,obj.id.replace(this.id+'_',''));  //on valid le champs
	switch(obj.id.replace(this.id+'_',''))
	{
	  case 'h':
	  case 's':
	  case 'v':
		var rgb=HSV2RGB(Array(this.get('h'),this.get('s'),this.get('v')));
		var cmyk=RGB2CMYK(rgb);
		this.set('hex',RGB2HEX(rgb));
		rgb=RGB2Array(rgb);
		this.set('r',rgb[0]); this.set('g',rgb[1]); this.set('b',rgb[2]);
		this.set('c',cmyk[0]); this.set('m',cmyk[1]); this.set('y',cmyk[2]); this.set('k',cmyk[3]);
		break;
	  case 'hex':
		var rgb=HEX2RGB(this.get('hex'));
		var cmyk=RGB2CMYK(rgb);
		var hsv=RGB2HSV(rgb);
		rgb=RGB2Array(rgb);
		this.set('r',rgb[0]); this.set('g',rgb[1]); this.set('b',rgb[2]);
		this.set('h',hsv[0]); this.set('s',hsv[1]); this.set('v',hsv[2]);
		this.set('c',cmyk[0]); this.set('m',cmyk[1]); this.set('y',cmyk[2]); this.set('k',cmyk[3]);
		break;
	  case 'r':
	  case 'g':
	  case 'b':
		var rgb='rgb('+this.get('r')+','+this.get('g')+','+this.get('b')+')';
		this.set('hex',RGB2HEX(rgb));
		var cmyk=RGB2CMYK(rgb);
		var hsv=RGB2HSV(rgb);
		this.set('h',hsv[0]); this.set('s',hsv[1]); this.set('v',hsv[2]);
		this.set('c',cmyk[0]); this.set('m',cmyk[1]); this.set('y',cmyk[2]); this.set('k',cmyk[3]);
		break;
	  case 'c':
	  case 'm':
	  case 'y':
	  case 'k':
		var rgb=CMYK2RGB(Array(this.get('c'),this.get('m'),this.get('y'),this.get('k')));
		this.set('hex',RGB2HEX(rgb));
		rgb=RGB2Array(rgb);
		var cmyk=RGB2CMYK(rgb);
		var hsv=RGB2HSV(rgb);
		this.set('r',rgb[0]); this.set('g',rgb[1]); this.set('b',rgb[2]);
		this.set('h',hsv[0]); this.set('s',hsv[1]); this.set('v',hsv[2]);
		break;
	}
	
	//on repositionne le curseur Z
	var zvalue=Math.round(this.get(this.actualZ));//obj.id.replace(this.id+'_','')
	if(this.actualZ=='h') { zvalue=Math.round(resampleColor(zvalue,360,255,true)); }
	if(this.actualZ=='s' || this.actualZ=='v') { zvalue=Math.round(resampleColor(zvalue,100,255,true)); }
	zvalue=255-zvalue;
	this.zPointer.style.top=(Math.round(this.yDecal-4+zvalue))+'px';
	
	//on repositionne le curseur XY
	var xvalue=0;
	var yvalue=0;
	switch(this.actualZ)
	{
		case 'r':
			xvalue=Math.round(this.get('b'));
			yvalue=255-Math.round(this.get('g'));
			break;
		case 'g':
			xvalue=Math.round(this.get('b'));
			yvalue=255-Math.round(this.get('r'));
			break;
		case 'b':
			xvalue=Math.round(this.get('r'));
			yvalue=255-Math.round(this.get('g'));
			break;
		case 'h':
			xvalue=resampleColor(Math.round(this.get('s')),100,255,true);
			yvalue=255-resampleColor(Math.round(this.get('v')),100,255,true);
			break;
		case 's':
			xvalue=resampleColor(Math.round(this.get('h')),360,255,true);
			yvalue=255-resampleColor(Math.round(this.get('v')),100,255,true);
			break;
		case 'v':
			xvalue=resampleColor(Math.round(this.get('h')),360,255,true);
			yvalue=255-resampleColor(Math.round(this.get('s')),100,255,true);
			break;
	}
	this.xyPointer.style.left=(Math.round(this.xDecal-5+xvalue))+'px';
	this.xyPointer.style.top=(Math.round(this.yDecal-5+yvalue))+'px';
	
	//on lance les rafraichissement graphiques
	
	this.drawVariableSpace();
	this.drawGrid();
	this.refreshCurrentColor(); //	isWebSafeColor();
}

//traitement de changement de palette/sélecteur
function CP_changeSelector(label)
{
	//on masque tous les pluggins
	this.hidePlugginsSelector();
	
	if(label!='perceptual')
	{
		if(this.selecteurMode=='perceptual')
		{//cela veut dire que l'on va pouvoir masquer le selecteur de qualite et d'iminuer la precision d'affichage
			this.bottomQualityTd.innerHTML='&nbsp;';
			this.precisionBeforeTabPannelSwitch=this.step;
			this.changePrecision(1);
		}
		//puis on active celui qui a le bon id  (cf label)
		for(var i=0 ; i<this.pluggins.length ; i++)
		{
			if(this.pluggins[i].codeName==label)
			{
				this.pluggins[i].showSelector();
				this.xyPointer.style.display='none';
				this.zPointer.style.display='none';
			}
		}
	}
	
	if(label=='perceptual') //retour a la bonne precision voulu  this.selecteurMode!='perceptual' && 
	{
		this.bottomQualityTd.innerHTML=CP_quality_selector_string.replace('##ColorPicker.id##',this.id);
		this.changePrecision(this.precisionBeforeTabPannelSwitch,true);
		this.xyPointer.style.display='block';
		this.zPointer.style.display='block';
	}
	
	this.selecteurMode=label;
	document.getElementById(this.id+'_paletteSelector').value=this.selecteurMode;
	createCookie(this.id+'_last_mode_used',this.selecteurMode,null,HISTORY_COOKIES_DOMAIN_PATH);
	return;
}

//fonction construisant tout le code HTML du color picker
// puis inject se code dans le container definit dans le constructeur du ColorPicker (cf this.obj)
function CP_injectHTML()
{
   var html='<table border="0" cellpadding="0" cellspacing="0" id="'+this.id+'_table" class="colorPicker">';
   html+='  <tr>';
   html+='    <td class="colorpickerTdNO">&nbsp;</td>';
   html+='    <td class="colorpickerTdN">&nbsp;</td>';
   html+='    <td class="colorpickerTdNE">&nbsp;</td>';
   html+='  </tr>';
   html+='  <tr>';
   html+='    <td class="colorpickerTdO">&nbsp;</td>';
   html+='    <td class="colorpickerTdContent"><table width="100%" height="286" border="0" cellpadding="0" cellspacing="0">';
   html+='      <tr>';
   html+='        <td height="30" style="width:286px; height:30px;"><select class="paletteSelector" id="'+this.id+'_paletteSelector" onChange="CP_colorPickerChangeSelectorHandler(this);">';
   html+='          <option value="perceptual">'+CP_LOCAL_mode_perceptual+'</option>';
   html+='        </select>        </td>';
   html+='        <td rowspan="2" style="width:10px;">&nbsp;</td>';
   html+='        <td rowspan="2" style="width:250px;"><table border="0" cellpadding="0" cellspacing="0" style="width:250px; height:286px;">';
   html+='          <tr>';
   html+='            <td style="width:100px;" align="center"><table border="0" cellspacing="0" cellpadding="0" style="width:90px; height:72px;">';
   html+='                <tr>';
   html+='                  <td rowspan="2" id="'+this.id+'_currentSpace"><img src="images/empty.gif" id="'+this.id+'_currentSpaceArea" style="cursor:pointer; width:75px; height:36px;" title="'+CP_LOCAL_message_to_put_in_history+'" onDblClick="CP_setHistory(event);"></td>';
   html+='                  <td style="width:15px; height:18px;" id="'+this.id+'_Warning0Td">&nbsp;</td>';
   html+='                </tr>';
   html+='                <tr>';
   html+='                  <td style="width:15px; height:18px;" id="'+this.id+'_Warning1Td">&nbsp;</td>';
   html+='                </tr>';
   html+='                <tr>';
   html+='                  <td rowspan="2" id="'+this.id+'_currentSpaceOld"><img id="'+this.id+'_currentSpaceOldArea" style="cursor:pointer; width:75px; height:36px;" onDblClick="CP_loadInitialColor(event);" src="images/empty.gif" title="'+CP_LOCAL_message_restore_this_color+'"></td>';
   html+='				  <td style="width:15px; height:18px;" id="'+this.id+'_Warning2Td">&nbsp;</td>';
   html+='                </tr>';
   html+='				<tr>';
   html+='				  <td style="width:15px; height:18px;" id="'+this.id+'_Warning3Td">&nbsp;</td>';
   html+='				</tr>';
   html+='            </table></td>';
   html+='            <td align="center" style="width:150px;">';
   html+='			<!-- HISTORIQUE PANEL -->';
   html+='				<table width="145" height="70" border="0" cellpadding="0" cellspacing="1">';
   html+='				  <tr>';
   html+='					<td id="'+this.id+'_historyTd_0" class="colorpickerTdHistory" style="border: solid 1px '+HISTORY_BORDER_SELECTED_COLOR+';"><img id="'+this.id+'_historyArea_0" onClick="CP_historyClickHandler(event);" onDblClick="CP_histotyDblClickHandler(event);" class="colorpickerImgHistory" src="images/empty.gif" title="'+CP_LOCAL_message_restore_this_color+'"></td>';
for(var i=1 ; i<6 ; i++)
   {
   html+='					<td id="'+this.id+'_historyTd_'+i+'" class="colorpickerTdHistory"><img id="'+this.id+'_historyArea_'+i+'" onClick="CP_historyClickHandler(event);" onDblClick="CP_histotyDblClickHandler(event);" class="colorpickerImgHistory" src="images/empty.gif" title="'+CP_LOCAL_message_restore_this_color+'"></td>';
   }
   html+='				  </tr>';
   html+='				  <tr>';
   for(var i=6 ; i<12 ; i++)
   {
   html+='					<td id="'+this.id+'_historyTd_'+i+'" class="colorpickerTdHistory"><img id="'+this.id+'_historyArea_'+i+'" onClick="CP_historyClickHandler(event);" onDblClick="CP_histotyDblClickHandler(event);" class="colorpickerImgHistory" src="images/empty.gif" title="'+CP_LOCAL_message_restore_this_color+'"></td>';
   }
   html+='				  </tr>';
   html+='				  <tr>';
   for(var i=12 ; i<18 ; i++)
   {
   html+='					<td id="'+this.id+'_historyTd_'+i+'" class="colorpickerTdHistory"><img id="'+this.id+'_historyArea_'+i+'" onClick="CP_historyClickHandler(event);" onDblClick="CP_histotyDblClickHandler(event);" class="colorpickerImgHistory" src="images/empty.gif" title="'+CP_LOCAL_message_restore_this_color+'"></td>';
   }
   html+='				  </tr>';
   html+='				</table>';
   html+='			</td>';
   html+='          </tr>';
   html+='          <tr>';
   html+='            <td colspan="2" style="height:180px;"><!--  TABLEAU DES INPUTS KEYBOARD NUMERIQUE-->';
   html+='                <table border="0" cellpadding="0" cellspacing="0" style="width:250px;">';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" value="radiobutton" style="width:inherit;" id="'+this.id+'_Z_H" onChange="CP_changeZAxisHandler(this);" tabindex="15"></td>';
   html+='                    <td width="20" align="center"><strong>H</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_h" onChange="CP_changeHandler(this);" value="0" maxlength="3" tabindex="1"></td>';
   html+='                    <td width="40">&deg;</td>';
   html+='                    <td colspan="3" rowspan="4" style="width:100px; height:82px;" align="center" id="'+this.id+'_emptyZoneTd"><a href="http://codessources.votre-web.com" target="_blank" style="text-decoration:none; color:#000066; font-weight:bold; font-size:10px;">Created by<br>By MaX3315</a></td>';
   html+='                    </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" value="radiobutton" style="width:inherit; " id="'+this.id+'_Z_S" onChange="CP_changeZAxisHandler(this);" tabindex="16"></td>';
   html+='                    <td width="20" align="center"><strong>S</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_s" onChange="CP_changeHandler(this);" value="100" maxlength="3" tabindex="2"></td>';
   html+='                    <td width="40">%</td>';
   html+='                    </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" value="radiobutton" style="width:inherit; " id="'+this.id+'_Z_V" onChange="CP_changeZAxisHandler(this);" tabindex="17"></td>';
   html+='                    <td width="20" align="center"><strong>V</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_v" onChange="CP_changeHandler(this);" value="100" maxlength="3" tabindex="3"></td>';
   html+='                    <td width="40">%</td>';
   html+='                    </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right">&nbsp;</td>';
   html+='                    <td width="20" align="right">&nbsp;</td>';
   html+='                    <td width="50">&nbsp;</td>';
   html+='                    <td width="40">&nbsp;</td>';
   html+='                    </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" style="width:inherit; " value="radiobutton" checked id="'+this.id+'_Z_R" onChange="CP_changeZAxisHandler(this);" tabindex="18"></td>';
   html+='                    <td width="20" align="center"><strong>R</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_r" onChange="CP_changeHandler(this);" value="255" maxlength="3" tabindex="4"></td>';
   html+='                    <td width="40">&nbsp;</td>';
   html+='                    <td width="20" align="center"><strong>C</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_c" onChange="CP_changeHandler(this);" value="0" maxlength="3" tabindex="8"></td>';
   html+='                    <td width="20">%</td>';
   html+='                  </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" value="radiobutton" style="width:inherit; " id="'+this.id+'_Z_G" onChange="CP_changeZAxisHandler(this);" tabindex="19"></td>';
   html+='                    <td width="20" align="center"><strong>G</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_g" onChange="CP_changeHandler(this);" value="0" maxlength="3" tabindex="5"></td>';
   html+='                    <td width="40">&nbsp;</td>';
   html+='                    <td width="20" align="center"><strong>M</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_m" onChange="CP_changeHandler(this);" value="100" maxlength="3" tabindex="9"></td>';
   html+='                    <td width="20">%</td>';
   html+='                  </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><input name="'+this.id+'_Z_SELECT" type="radio" value="radiobutton" style="width:inherit; " id="'+this.id+'_Z_B" onChange="CP_changeZAxisHandler(this);" tabindex="20"></td>';
   html+='                    <td width="20" align="center"><strong>B</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_b" onChange="CP_changeHandler(this);" value="0" maxlength="3" tabindex="6"></td>';
   html+='                    <td width="40">&nbsp;</td>';
   html+='                    <td width="20" align="center"><strong>Y</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_y" onChange="CP_changeHandler(this);" value="100" maxlength="3" tabindex="10"></td>';
   html+='                    <td width="20">%</td>';
   html+='                  </tr>';
   html+='                  <tr>';
   html+='                    <td width="40" align="right"><strong>Hex</strong></td>';
   html+='                    <td colspan="2" align="right"><input name="text" type="text" id="'+this.id+'_hex" onChange="CP_changeHandler(this);" value="#ff0000" size="7" maxlength="7" tabindex="7"></td>';
   html+='                    <td width="40">&nbsp;</td>';
   html+='                    <td width="20" align="center"><strong>K</strong></td>';
   html+='                    <td width="50"><input name="text" type="text" id="'+this.id+'_k" onChange="CP_changeHandler(this);" value="0" maxlength="3" tabindex="11"></td>';
   html+='                    <td width="20">%</td>';
   html+='                  </tr>';
   html+='              </table></td>';
   html+='          </tr>';
   html+='          <tr>';
   html+='            <td colspan="2" style="height:25px; width:250px;" id="'+this.id+'_qualityTd" class="qualitySelectorTd">'+CP_quality_selector_string.replace('##ColorPicker.id##',this.id)+'</td>';
   html+='          </tr>';
   html+='        </table></td>';
   html+='      </tr>';
   html+='      <tr>';
   html+='        <td width="286" height="256">';
   html+='			<!-- conteneur du selecteur percetuel -->';
   html+='			<table width="286" height="256" border="0" cellpadding="0" cellspacing="0" id="'+this.id+'_perceptualSelectorTable">';
   html+='			  <tr>';
   html+='				<!-- zone de 256x256 px -->';
   html+='				<td width="256" height="256">';
   html+='				  <!--Les pointers-->';
   html+='				  <div id="'+this.id+'_pointerXY" class="pointerXY"><img src="images/pointerXY.gif" alt="pointer" width="11" height="11"></div>';
   html+='				  <div id="'+this.id+'_pointerZ" class="pointerZ"><img src="images/pointerZ.gif" alt="pointer" width="36" height="9"></div>';
   html+='				  <!--L\'espace 2D (x et y)-->';
   html+='					<div id="'+this.id+'_variationEspace" style="width:256px; height:256px; position:absolute; display:none; top:0px; left:0px; border:none;" tabindex="12"></div>';
   html+='				  <div id="'+this.id+'_dragXY" style="width:256px; height:256px; z-index:9; position:absolute; top:0px; left:0px; border:none; cursor:crosshair; display:none;" onMouseMove="CP_moveXYHandler(event);" onClick="CP_mouseMode=\'xy\'; CP_moveXYHandler(event); CP_mouseMode=\'up\';" onMouseDown="CP_mouseMode=\'xy\';" onMouseUp="CP_mouseMode=\'up\';" onMouseOut="CP_mouseMode=\'up\';"></div></td>';
   html+='				<!-- fin de la zone 256x256-->';
   html+='				<!-- margin spacer 10px with-->';
   html+='				<td width="10" height="256">&nbsp;</td>';
   html+='				<!-- vertical selcetor zone 20x256px -->';
   html+='				<td width="20" height="256"><!--L\'espace vertical (z)-->';
   html+='					<div id="'+this.id+'_variableEspace" style="display:none; width:20px; height:256px; z-index:2; position:absolute; top:0px; left:0px; border:none;" tabindex="13"></div>';
   html+='				  <div id="'+this.id+'_dragZ" style="display:none; width:20px; height:256px; z-index:9; position:absolute; top:0px; left:0px; border:none; cursor:crosshair;" onMouseMove="CP_moveZHandler(event);" onClick="CP_mouseMode=\'z\'; CP_moveZHandler(event); CP_mouseMode=\'up\';" onMouseDown="CP_mouseMode=\'z\';" onMouseUp="CP_mouseMode=\'up\';" onMouseOut="CP_mouseMode=\'up\';"></div></td>';
   html+='			  </tr>';
   html+='        	</table>		</td>';
   html+='        </tr>';
   html+='    </table></td>';
   html+='    <td class="colorpickerTdE">&nbsp;</td>';
   html+='  </tr>';
   html+='  <tr>';
   html+='    <td class="colorpickerTdSO">&nbsp;</td>';
   html+='    <td class="colorpickerTdS">&nbsp;</td>';
   html+='    <td class="colorpickerTdSE">&nbsp;</td>';
   html+='  </tr>';
   html+='</table>';
  this.obj.innerHTML=html;
  return;
}
